let handCardService = module.exports;

let configuration = require('../../configuration');

let game;
let handCards = {
    'bottom': [],
    'top': []
};

handCardService.init = function (initConfig) { // {game: ...}
    game = initConfig.game;
};

handCardService.addCard = function (side, cards) {
    for (let card of cards) {
        handCards[side].push(card);
        card.mode = 'inHand';
    }
    arrange(side, handCards[side]);
};

// card moved out of field
// remove the card from hand
handCardService.onComponentRemoved = function (sender, o) {
    removeCard(o);
};

// a slot accepts a card
// remove the card from hand
handCardService.onAcceptCardMove = function (sender, info) {
    let card = info.card;
    removeCard(card);
};

handCardService.reorder = function (side, orderList) { // orderList = [oldIndex1, oldIndex2, ...]
    let array = handCards[side];
    let newArray = [];
    for (let i = 0; i < orderList.length; ++i) {
        let c = array[i];
        newArray.push(c);
    }
    handCards[side] = newArray;
    arrange(side, newArray);
};

function removeCard(card) {
    out:for (let k in handCards) {
        let array = handCards[k];
        for (let i = 0; i < array.length; ++i) {
            let elem = array[i];
            if (elem === card) {
                array.splice(i, 1);
                arrange(k, array);
                break out;
            }
        }
    }
}

function arrange(side, array) {
    if (array.length === 0) return;
    let windowHeight = configuration.get('window.height');
    let cardWidth = configuration.get('components.card.thumb.width');
    let cardHeight = configuration.get('components.card.thumb.height');
    let vMargin = configuration.get('components.slot.vMargin');

    let y;
    if (side === 'bottom') {
        y = windowHeight - vMargin * 2 - cardHeight / 2;
    } else {
        y = vMargin + cardHeight / 2;
    }
    let xs = [];
    let leftSideBarWidth = configuration.get('components.leftSideBar.width');
    let hMargin = configuration.get('components.slot.hMargin');
    let leftSideBarMarginRight = configuration.get('components.leftSideBar.marginRight');
    let slotA = cardWidth > cardHeight ? cardWidth : cardHeight;
    let steps = [];
    if (side === 'bottom') {
        steps.push({
            width: slotA * 5 + hMargin * 4,
            startX: leftSideBarWidth + leftSideBarMarginRight + cardWidth + hMargin
        });
        steps.push({
            width: slotA * 5 + hMargin * 5 + cardWidth,
            startX: leftSideBarWidth + leftSideBarMarginRight
        });
        steps.push({
            width: leftSideBarMarginRight + slotA * 5 + hMargin * 5 + cardWidth,
            startX: leftSideBarWidth
        });
    } else {
        steps.push({
            width: slotA * 5 + hMargin * 4,
            startX: leftSideBarWidth + leftSideBarMarginRight + cardWidth + hMargin
        });
        steps.push({
            width: slotA * 5 + hMargin * 5 + cardWidth,
            startX: leftSideBarWidth + leftSideBarMarginRight
        });
    }
    // determine which step is used
    let totalWidth = cardWidth * array.length + hMargin * (array.length - 1);
    let useStep = -1;
    for (let i = 0; i < steps.length; ++i) {
        let step = steps[i];
        if (step.width > totalWidth) {
            useStep = i;
            break;
        }
    }
    let handCardMargin;
    if (useStep === -1) {
        // not found, calculate the min margin
        let minWidth = cardWidth * array.length;
        handCardMargin = (steps[steps.length - 1].width - minWidth) / (array.length - 1);
        useStep = steps.length - 1;
    } else {
        handCardMargin = hMargin;
    }
    let startX = steps[useStep].startX;
    let mostRight = leftSideBarWidth + leftSideBarMarginRight + cardWidth + 5 * (hMargin + slotA);
    let middle = (startX + mostRight) / 2;
    if (array.length % 2 === 0) {
        startX = middle - handCardMargin / 2 - cardWidth * array.length / 2 - (array.length / 2 - 1) * handCardMargin;
    } else {
        startX = middle - cardWidth / 2 - (array.length - 1) / 2 * (handCardMargin + cardWidth);
    }
    if (side === 'bottom') {
        for (let i = 0; i < array.length; ++i) {
            xs.push(startX + cardWidth / 2);
            startX += (cardWidth + handCardMargin);
        }
    } else {
        startX = middle * 2 - startX + cardWidth + vMargin;
        for (let i = 0; i < array.length; ++i) {
            xs.push(startX - cardWidth / 2);
            startX -= (cardWidth + handCardMargin);
        }
    }
    // move animation
    for (let i = 0; i < xs.length; ++i) {
        let card = array[i];
        let x = xs[i];
        card.onCardAnimation(this, {
            compId: card.compId,
            operation: 'move',
            x: x,
            y: y,
            period: 0.2 * 1000
        });
    }
    // arrange zIndex
    for (let i = 0; i < array.length; ++i) {
        let card = array[i];
        let container = card.componentContainer;
        container.setZIndex(card, 1 + i);
    }
}
